import {
    init,
    classModule,
    propsModule,
    styleModule,
    eventListenersModule,
    h,
} from "snabbdom"

const patch = init([
    classModule,
    propsModule,
    styleModule,
    eventListenersModule,
])

let vnode

// 下一个 key 值
let nextKey = 11
// 电影列表之间的间距值
const margin = 8
// 初始排序类型，初始为 desc
let sortBy = "desc"
// 整体高度
let totalHeight = 0
// 页面数据
const originalData = [
    {
        rank: 8,
        title: "The Good, the Bad and the Ugly",
        desc: "A bounty hunting scam joins two men in an uneasy alliance against a third in a race to find a fortune in gold buried in a remote cemetery.",
        elmHeight: 0,
    },
    {
        rank: 7,
        title: "12 Angry Men",
        desc: "A dissenting juror in a murder trial slowly manages to convince the others that the case is not as obviously clear as it seemed in court.",
        elmHeight: 0,
    },
    {
        rank: 10,
        title: "Fight Club",
        desc: "An insomniac office worker looking for a way to change his life crosses paths with a devil-may-care soap maker and they form an underground fight club that evolves into something much, much more...",
        elmHeight: 0,
    },
]

let data = [
    originalData[0],
    originalData[1],
    originalData[2],
]

// 更改排序
function changeSort (prop) {
    sortBy = prop
    data.sort((a, b) => {
        if (a[prop] > b[prop]) return 1
        if (a[prop] < b[prop]) return -1
        return 0
    })
    render()
}

// 添加元素
function add () {
    // 随机获取一个数据
    const newList = originalData[Math.floor(Math.random() * originalData.length)]
    // 与原数据合并
    data = [
        { rank: nextKey++, title: newList.title, desc: newList.desc, elmHeight: 0 },
    ].concat(data)
    // 初始元素
    render()
    // 初始排序动画
    render()
}

// 删除元素
function remove (movie) {
    data = data.filter(m => m !== movie)
    render()
}

// 电影列表数据
function movieView (movie) {
    return h(
        "div.row",
        {
            key: movie.rank,
            style: {
                opacity: "0",
                transform: "translate(-200px)",
                delayed: { transform: `translateY(${movie.offset}px)`, opacity: "1" },
                remove: {
                    opacity: "0",
                    transform: `translateY(${movie.offset}px) translateX(200px)`,
                },
            },
            hook: {
                // insert 钩子中初始化 elmHeight 的值（高度）
                insert: (vnode) => {
                    movie.elmHeight = vnode.elm.offsetHeight
                },
            },
        },
        [
            h("div", { style: { fontWeight: "bold" } }, movie.rank),
            h("div", movie.title),
            h("div", movie.desc),
            h(
                "div.btn.rm-btn",
                {
                    on: {
                        click: () => { remove(movie) },
                    },
                },
                "x"
            ),
        ]
    )
}

// 渲染
function render () {
    data = data.reduce((acc, m) => {
        const last = acc[acc.length - 1]
        m.offset = last ? last.offset + last.elmHeight + margin : margin
        return acc.concat(m)
    }, [])

    totalHeight = data.length === 0 ? 0 : data[data.length - 1].offset + data[data.length - 1].elmHeight

    vnode = patch(vnode, view(data))
}

// 页面 vnode 
function view (data) {
    return h("div", [
        h("h1", "Top 10 movies"),
        h("div", [
            // 增减按钮
            h("a.btn.add", { on: { click: add } }, "Add"),
            "Sort by: ",
            // 排序按钮
            h("span.btn-group", [
                h(
                    "a.btn.rank",
                    {
                        class: { active: sortBy === "rank" },
                        on: {
                            click: () => { changeSort("rank") },
                        },
                    },
                    "Rank"
                ),
                h(
                    "a.btn.title",
                    {
                        class: { active: sortBy === "title" },
                        on: {
                            click: () => { changeSort("title") },
                        },
                    },
                    "Title"
                ),
                h(
                    "a.btn.desc",
                    {
                        class: { active: sortBy === "desc" },
                        on: {
                            click: () => { changeSort("desc") },
                        },
                    },
                    "Description"
                ),
            ]),
        ]),
        // 电影列表
        h(
            "div.list",
            { style: { height: totalHeight + "px" } },
            data.map(movieView)
        ),
    ])
}


// 当纯HTML被完全加载以及解析时，DOMContentLoaded 事件会被触发
// window.addEventListener("DOMContentLoaded", () => {
//     const container = document.getElementById("container")
//     vnode = patch(container, view(data))
//     render()
// })

const container = document.getElementById("container")
vnode = patch(container, view(data))
render()
